'use strict'

import {app, protocol, ipcMain, BrowserWindow, dialog} from 'electron'
import {
    createProtocol,
    installVueDevtools
} from 'vue-cli-plugin-electron-builder/lib'
// import {init} from './utils/socket-helper'
// 引入自动更新模块
import {autoUpdater} from 'electron-updater'

const feedUrl = process.env.VUE_ELECTRON_UPDATE_URL; // 更新包位置

const isDevelopment = process.env.NODE_ENV !== 'production'

import pkg from '../package.json'
import {delStore} from "./utils/storage";
import {unbindindCloudPrinterClientId} from "./api/webSocket";

const ApplicationName = pkg.name;
// 引入自动启动模块
const startOnBoot = require('./utils/auto-launch.js')

const log = require('electron-log');
log.transports.console.level = false;
log.transports.console.level = 'silly';

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win, loginWindow, navToTemp;

const loginURL = process.env.NODE_ENV === 'development'
    ? `http://localhost:8080/#login`
    : `app://./index.html#login`

const settingURL = process.env.NODE_ENV === 'development'
    ? `http://localhost:8080/#setting`
    : `app://./index.html#setting`

// 单一实例
const gotTheLock = app.requestSingleInstanceLock();

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{scheme: 'app', privileges: {secure: true, standard: true}}])

function createWindow() {
    // Create the browser window.
    win = new BrowserWindow(
        {
            width: 800,
            height: 600,
            frame: false,
            fullscreen: true, // 全屏
            webPreferences: {
                devTools: true,
                nodeIntegration: true
            },
        });
    win && win.hide();
    if (process.env.WEBPACK_DEV_SERVER_URL) {
        // Load the url of the dev server if in development mode
        win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
        if (isDevelopment) win.webContents.openDevTools()
    } else {
        createProtocol('app');
        // win.webContents.openDevTools();
        // Load the index.html when not in development
        win.loadURL('app://./index.html')
    }

    win.on('closed', () => {
        win = null
    });

    win.webContents.on('crashed', () => {
        recordCrash().then(() => {
            dialog.showMessageBox({
                type: 'error',
                title: '进程崩溃了',
                message: '这个进程已经崩溃.',
                buttons: ['重载', '退出'],
            }, (index) => {
                if (index === 0) win.reload();
                else app.quit();
            });
        }).catch((e) => {
            console.log('err', e);
        });
    })
}
function recordCrash() {
    return new Promise(resolve => {
        // 崩溃日志请求成功....
        resolve();
    })
}

function reloadWindow(win) {
    if (win.isDestroyed()) {
        app.relaunch();
        app.exit(0);
    } else {
        BrowserWindow.getAllWindows().forEach((w) => {
            if (w.id !== win.id) w.destroy();
        });
        win.reload();
    }
}

//开机启动
function ipcStartOnBoot() {
    // 检查是否自动启动
    ipcMain.on('getAutoStartValue', () => {
        startOnBoot.getAutoStartValue(ApplicationName, (error, result) => {
            if (error) {
                win.webContents.send('getAutoStartValue', false)
            } else {
                win.webContents.send('getAutoStartValue', true)
            }
        })
    })

    // 设置开机自动启动
    ipcMain.on('enableAutoStart', () => {
        startOnBoot.enableAutoStart(ApplicationName, process.execPath)
    });

    // 取消开机自动启动
    ipcMain.on('disableAutoStart', () => {
        startOnBoot.disableAutoStart(ApplicationName)
    })
}


/**
 * 创建登录主窗口
 */
function createLoginWindow() {
    if (loginWindow) {
        return
    }

    /**
     * Initial window options
     */
    loginWindow = new BrowserWindow({
        show: true,
        height: 360,
        width: 300,
        maxHeight: 360,
        maxWidth: 300,
        hasShadow: true,
        useContentSize: true,
        frame: false, // 无边框
        transparent: true, // 透明
        resizable: false,
        maximizable: false,
        minimizable: false,
        webPreferences: {
            devTools: true,
            nodeIntegration: true
        },
    });
    if (isDevelopment) loginWindow.webContents.openDevTools({mode: 'detach'});
    loginWindow.loadURL(loginURL);
    // loginWindow && loginWindow.hide();

    // 为了防止闪烁，让画面准备好了再显示
    // 对于一个复杂的应用，ready-to-show 可能发出的太晚，会让应用感觉缓慢。 在这种情况下，建议立刻显示窗口，并使用接近应用程序背景的 backgroundColor
    // 请注意，即使是使用 ready-to-show 事件的应用程序，仍建议使用设置 backgroundColor 使应用程序感觉更原生。
    loginWindow.once('ready-to-show', () => {

        loginWindow.show()
    });

    loginWindow.on('close', (event) => {

    });

    loginWindow.on('closed', () => {
        loginWindow = null
    });

    ipcMain.on('openLoginWindow', (event, arg) => {
        if (!loginWindow) {
            createLoginWindow()
        }
        navToTemp = arg;
        win && win.hide();
        loginWindow.show();
        loginWindow.focus()
    });

    ipcMain.on('openWindow', () => {
        navTo()
    })
}

function navTo() {
    if (navToTemp === 'toSetting') {
        if (!win) {
            createWindow()
        }
        loginWindow && loginWindow.destroy();
        win.show();
        win.loadURL(settingURL);
        win.focus()
    } else {
        if (!win) {
            createWindow()
        }
        loginWindow && loginWindow.destroy();
        win.show();
        win.focus()
        // init();
    }
}

// 主进程主动发送消息给渲染进程函数，提示更新信息
function sendUpdateMessage(obj) {
    win.webContents.send('updateMessage', obj)
}

//自动更新
function autoUpdate() {
    autoUpdater.setFeedURL(feedUrl);
    // 监测更新，各种状态的消息提示
    const message = {
        error: '检查更新出错',
        checking: '正在检查更新......',
        updateAva: '监测到新版本，正在下载......',
        updateNotAva: '现在使用的就是最新版本，不用下载'
    };

    // 当更新出现错误时触发
    autoUpdater.on('error', (err) => {
        // sendUpdateMessage('error')
        sendUpdateMessage({action: 'error', errorInfo: err})
    });

    // 当开始检查更新的时候触发
    autoUpdater.on('checking-for-update', () => {
        // sendUpdateMessage('checking')
        sendUpdateMessage({action: 'checking'})
    });

    // 当发现一个可用更新的时候触发，更新下载包会自动开始
    autoUpdater.autoDownload = false
    autoUpdater.on('update-available', (info) => {
        // sendUpdateMessage('updateAva')
        sendUpdateMessage({action: 'updateAva', updateInfo: info})
    });

    // 当没有可用更新的时候触发
    autoUpdater.on('update-not-available', (info) => {
        // sendUpdateMessage('updateNotAva')
        sendUpdateMessage({action: 'updateNotAva', updateInfo: info})
    });

    // 更新下载进度事件
    autoUpdater.on('download-progress', (progressObj) => {
        log.warn('触发下载');
        win.webContents.send('downloadProgress', progressObj)
    });
    /**
     * event Event
     * releaseNotes String - 新版本更新公告
     * releaseName String - 新的版本号
     * releaseDate Date - 新版本发布的日期
     * updateUrl String - 更新地址
     */
    autoUpdater.on('update-downloaded', (info) => {
        log.warn('开始更新');
        // 下载太快可能无法触发downloadProgress事件，所以手动通知一下
        win.webContents.send('downloadProgress', {percent: 100});
        // 可以手动选择是否立即退出并更新
        ipcMain.on('isUpdateNow', (e, arg) => {
            // some code here to handle event
            autoUpdater.quitAndInstall()
        })
    });

    ipcMain.on('checkForUpdate', () => {
        log.warn('执行自动更新检查');
        // 执行自动更新检查
        autoUpdater.checkForUpdates()
    })

    ipcMain.on('downloadUpdate', () => {
        log.warn('执行下载')
        // 下载
        autoUpdater.downloadUpdate()
    })
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
});

app.on('activate', () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (win === null) {
        createWindow()
    }
    if (loginWindow === null) {
        createLoginWindow()
    }
});


/**
 * 单一实例
 */
if (!gotTheLock) {
    app.quit()
} else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
        // 当运行第二个实例时,将会聚焦到myWindow这个窗口
        if (win) {
            if (win.isMinimized()) win.restore();
            win.focus()
        }
    });


    // This method will be called when Electron has finished
    // initialization and is ready to create browser windows.
    // Some APIs can only be used after this event occurs.
    app.on('ready', async () => {
        if (isDevelopment && !process.env.IS_TEST) {
            // Install Vue Devtools
            // Devtools extensions are broken in Electron 6.0.0 and greater
            // See https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378 for more info
            // Electron will not launch with Devtools extensions installed on Windows 10 with dark mode
            // If you are not using Windows 10 dark mode, you may uncomment these lines
            // In addition, if the linked issue is closed, you can upgrade electron and uncomment these lines
            // try {
            //   await installVueDevtools()
            // } catch (e) {
            //   console.error('Vue Devtools failed to install:', e.toString())
            // }

        }
        createWindow();
        ipcStartOnBoot();
        createLoginWindow();
        autoUpdate()
    })
}

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
    if (process.platform === 'win32') {
        process.on('message', data => {
            if (data === 'graceful-exit') {
                app.quit()
            }
        })
    } else {
        process.on('SIGTERM', () => {
            app.quit()
        })
    }
}

